package com.qianfeng.conf.interceptor;

import com.qianfeng.user.anno.Evade;
import com.qianfeng.user.util.CookieUtil;
import com.qianfeng.user.util.JWTTokenUtil;
import com.qianfeng.user.web.BaseController;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.SignatureException;
import org.apache.commons.lang3.StringUtils;
import org.springframework.boot.autoconfigure.web.servlet.error.AbstractErrorController;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.resource.ResourceHttpRequestHandler;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;

/**
 * 拦截器，如果没有token，直接返回结果。
 * @author Martin
 */
public class TokenInterceptor implements HandlerInterceptor {


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception{

        if(handler instanceof ResourceHttpRequestHandler || handler instanceof AbstractErrorController){
            return true;
        }

        System.out.println("start");

        HandlerMethod handlerMethod = (HandlerMethod)handler;

        //如果需要规避
        if(hasEvade(handlerMethod)){
            System.out.println("evade ： " +handlerMethod.toString());
            return true;
        }

        //从cookie中获取token
        String access_token = CookieUtil.getCookieValue(request, "access_token");

        //如果没有token，跳转到登录页面，这里需要判断一下是否是ajax请求
        if(StringUtils.isEmpty(access_token)){
            System.out.println("token is null");
            return vafail(request,response);
        }

        Claims claims = null;
        try{
            claims = JWTTokenUtil.phaseToken(access_token); //解析token
        }catch (ExpiredJwtException e){ //token已经过期
            System.out.println("token out time");
            return vafail(request,response);
        }catch (SignatureException e1){ //签名校验失败
            System.out.println("token signature fail");
            return vafail(request,response);
        }

        if(null != claims && !StringUtils.isEmpty(claims.get("uid").toString())){

            System.out.println("token success");

            //获取id，并将id设置到Controller

            if(handlerMethod.getBean() instanceof  BaseController){
                BaseController bean = (BaseController)handlerMethod.getBean();
                bean.setUserID(claims.get("uid").toString());
            }
            return true;
        }

        System.out.println("end");
        return false;
    }

    private boolean vafail(HttpServletRequest request,HttpServletResponse response) throws Exception{
        if(CookieUtil.isAjax(request)){
            response.getWriter().println("{'result':'6666','msg':'no token'}");
            return false;
        }
        response.sendRedirect("login");
        return false;
    }


    /**
     * 验证是否可以规避，不需要拦截
     * @param handlerMethod
     * @return
     */
    private boolean hasEvade(HandlerMethod handlerMethod){

        Method method = handlerMethod.getMethod();

        return method.getAnnotation(Evade.class) != null; //判断方法上面是否有自定义的规避注解。

    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        // TODO
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        // TODO
    }
}
